//
//  BLECMDType.swift
//  TimeBoat
//
//  Created by Jun on 2022/9/7.
//  Copyright © 2022 Time Boat. All rights reserved.
//

import Foundation

public enum BTLECMDType: UInt8 {
    // 命令头
    case BEGIN_CMD_HEADER = 0xAA
    
    // 数据包类型表：类型编码说明
    // 计步数据
    case STEP_COUNT = 0x01
    
    // 心率数据
    case HEART_RATE = 0x02
    
    // 睡眠监测数据
    case SLEEP = 0x03
    
    // 跑步运动数据
    case RUNNING = 0x04
    
    // 徒步运动数据
    case HIKING = 0x05
    
    // 马拉松训练数据
    case MARATHON = 0x06
    
    // 跳绳运动数据
    case SKIPPING_ROPE = 0x07
    
    // 游泳运动数据
    case SWIM = 0x08
    
    // 攀岩运动数据
    case ROCK_CLIMBING = 0x09
    
    // 滑雪运动数据
    case SKIING = 0x0A
    
    // 骑行运动数据
    case RIDE = 0x0B
    
    // 划船运动数据
    case BOAT = 0x0C
    
    // 蹦极运动数据
    case BUNGEE_JUMPING = 0x0D
    
    // 登山运动数据
    case MOUNTAINEERING = 0x0E
    
    // 跳伞运动数据
    case PARACHUTE_JUMP = 0x0F
    
    // 高尔夫运动数据
    case GOLF = 0x10
    
    // 冲浪运动数据
    case SURFING = 0x11
    
    // 气压检测数据
    case BAROMETRIC_PRESSURE = 0x12
    
    // SOS呼救
    case SOS = 0x13
    
    // 跑步机训练数据
    case RUNNING_MACHINE = 0x14
    
    // 拍照
    case PICTURE = 0x15
    
    // 寻找手机
    case FIND_PHONE = 0x16
    
    // 当前主动测量心率值
    case MEASURE_HEART_RATE = 0x17
    
    // 当前主动测量体温值
    case MEASURE_BODY_TEMPERATURE = 0x18
    
    // 计步总步数
    case TOTAL_STEP = 0x19
    
    // 手表改变配置信息
    case CHANGE_CONFIG = 0x20
    
    // 羽毛球
    case BADMINTON = 0x21
    
    // 篮球
    case BASKETBALL = 0x22
    
    // 足球
    case FOOTBALL = 0x23
    
    // 主动测量的血氧值
    case BLOOD_OXYGEN = 0x24
    
    // ======手机应用 -> 手表==========
    // 时间同步
    case SYNC_TIME = 0x30
    
    // 用户信息
    case USER_INFO = 0x31
    
    // 设备信息
    case DEVICE_INFO = 0x32
    
    // 天气
    case WEATHER = 0x33
    
    // 来电提醒
    case CALL_REMINDER = 0x34
    
    // 断开连接命令
    case DISCONNECT = 0x35
    
    // 设置巡航坐标
    case CRUISE_COORDINATE = 0x36
    
    // 寻找手表
    case FIND_WATCH = 0x38
    
    // 同步语言
    case SYNC_LANGUAGE = 0x39
    
    // 信息（短信、微信、QQ等）
    case MESSAGE = 0x40
    
    // 设置单位制式
    case SET_UNIT = 0x41
    
    // IOS系统通知拦截配置
    case IOS_NOTIFICATION_CONFIG = 0x42
    
    // 海拔校验数据
    case ALTITUDE_CALIBRATION = 0x43
    
    // 时间制式
    case TIME_UNIT = 0x44
    
    // 设置主动测量心率
    case SET_HEART_RATE = 0x45
    
    // 传输图片
    case TRANSFER_IMAGE = 0x46
    
    static func isHeader(c: UInt8) -> Bool {
        return c == BEGIN_CMD_HEADER.rawValue
    }
    
    static func isCMDTypeValid(c: UInt8) -> Bool {
        return (1...0x7f).contains(c)
    }
    
    static func buildCommandHeader(cmdType: UInt8, length: Int) -> [UInt8] {
        var item = [UInt8]()
        let timestamp = UInt32(Date().timeIntervalSince1970)
        
        item.append(BEGIN_CMD_HEADER.rawValue)
        item.append(cmdType)
        item.append(UInt8(length & 0xff))
        item.append(UInt8((length >> 8) & 0xff))
        item.append(UInt8(timestamp & 0xff))
        item.append(UInt8((timestamp >> 8) & 0xff))
        item.append(UInt8((timestamp >> 16) & 0xff))
        item.append(UInt8((timestamp >> 24) & 0xff))
        
        return item
    }
    
    static func buildStepCountCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: STEP_COUNT.rawValue, length: 0)
    }
    
    static func buildHeartRateCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: HEART_RATE.rawValue, length: 0)
    }
    
    static func buildSleepCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: SLEEP.rawValue, length: 0)
    }
    
    static func buildRunningCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: RUNNING.rawValue, length: 0)
    }
    
    static func buildHikingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: HIKING.rawValue, length: 0)
    }
    
    static func buildMarathonCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: MARATHON.rawValue, length: 0)
    }
    
    static func buildSkippingRopeCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: SKIPPING_ROPE.rawValue, length: 0)
    }
    
    static func buildSwimmingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: SWIM.rawValue, length: 0)
    }
    
    static func buildRockClimbingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: ROCK_CLIMBING.rawValue, length: 0)
    }
    
    static func buildSkiingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: SKIING.rawValue, length: 0)
    }
    
    static func buildRideCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: RIDE.rawValue, length: 0)
    }
    
    static func buildBoatCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: BOAT.rawValue, length: 0)
    }
    
    static func buildBungeeJumpingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: BUNGEE_JUMPING.rawValue, length: 0)
    }
    
    static func buildMountaineeringCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: MOUNTAINEERING.rawValue, length: 0)
    }
    
    static func buildParachuteJumpCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: PARACHUTE_JUMP.rawValue, length: 0)
    }
    
    static func buildGolfCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: GOLF.rawValue, length: 0)
    }
    
    static func buildSurfingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: SURFING.rawValue, length: 0)
    }
    
    static func buildPressureCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: BAROMETRIC_PRESSURE.rawValue, length: 0)
    }
    
    static func buildSOSCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: SOS.rawValue, length: 0)
    }
    
    static func buildRunTrainingCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: RUNNING_MACHINE.rawValue, length: 0)
    }
    
    static func buildPictureCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: PICTURE.rawValue, length: 0)
    }
    
    static func buildFindPhoneCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: FIND_PHONE.rawValue, length: 0)
    }
    
    static func buildMeasureHeartRateCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: MEASURE_HEART_RATE.rawValue, length: 0)
    }
    
    static func buildMeasureBodyTemperatureCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: MEASURE_BODY_TEMPERATURE.rawValue, length: 0)
    }
    
    static func buildTotalStepCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: TOTAL_STEP.rawValue, length: 0)
    }
    
    static func buildChangeConfigCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: CHANGE_CONFIG.rawValue, length: 0)
    }
    
    static func buildBadmintonCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: BADMINTON.rawValue, length: 0)
    }
    
    static func buildBasketballCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: BASKETBALL.rawValue, length: 0)
    }
    
    static func buildFootballCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: FOOTBALL.rawValue, length: 0)
    }
    
    static func buildBloodOxygenCMDHeader() -> [UInt8] {
        return buildCommandHeader(cmdType: BLOOD_OXYGEN.rawValue, length: 0)
    }
    
    // 年 2Byte
    // 月 1Byte
    // 日 1Byte
    // 时 1Byte
    // 分 1Byte
    // 秒 1Byte
    // 时区符号 1Byte //1:正时区 东部地区，0：负时区
    // 时区 1Byte //高 2 位代表时区，个位代表半点
    // 安卓手机标记 4byte = 0x78563412， 请参考下面注解，iOS端不传这4个字节
    static func buildSyncTimeCommand(timezoneType: UInt8 = 1) -> [UInt8] {
        let date = Date()
        let timeLength = 9
        let syncTimeHeaderArray = buildCommandHeader(cmdType: SYNC_TIME.rawValue, length: timeLength)
        
        let calendar = Calendar.default
        let year = calendar.component(.year, from: date)
        let month = calendar.component(.month, from: date)
        let day = calendar.component(.day, from: date)
        let hour = calendar.component(.hour, from: date)
        let minute = calendar.component(.minute, from: date)
        let second = calendar.component(.second, from: date)
        let timezone = 0x50
        var timeCommand = syncTimeHeaderArray
        timeCommand.append(UInt8(year & 0xff))
        timeCommand.append(UInt8((year >> 8) & 0xff))
        timeCommand.append(UInt8(month))
        timeCommand.append(UInt8(day))
        timeCommand.append(UInt8(hour))
        timeCommand.append(UInt8(minute))
        timeCommand.append(UInt8(second))
        timeCommand.append(UInt8(timezoneType))
        timeCommand.append(UInt8(timezone))
        
        return timeCommand
    }
}
